package com.tencent.yumeko;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

@RestController
@RequestMapping("/rate-limit")
public class RateLimitController {
    private static final Logger LOG = LoggerFactory.getLogger(RateLimitController.class);

    private final AtomicInteger index = new AtomicInteger(0);
    private final AtomicLong lastTimestamp = new AtomicLong(0);
    @Autowired
    private RestTemplate restTemplate;
    @Value("${spring.application.name}")
    private String appName;

    /**
     * Get information.
     *
     * @return information
     */
    //http://localhost:44444/rate-limit/info
    @GetMapping("/info")
    public String info() {
        return "通过单速率获取的信息。 " + index.incrementAndGet();
    }

    /**
     * 每 1 秒获取 30 次信息.
     *
     * @return 30 次调用的结果.
     * @throws InterruptedException exception
     */
    //http://localhost:44444/rate-limit/invoke
    @GetMapping("/invoke")
    public String invokeInfo() throws InterruptedException {
        StringBuffer builder = new StringBuffer();
        CountDownLatch count = new CountDownLatch(30);
        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                try {
                    ResponseEntity<String> entity = restTemplate.getForEntity("http://" + appName + "/rate-limit/info",
                            String.class);
                    builder.append(entity.getBody() + "\n");
                } catch (RestClientException e) {
                    if (e instanceof HttpClientErrorException.TooManyRequests) {
                        builder.append("请求过多 " + index.incrementAndGet() + "\n");
                    } else {
                        throw e;
                    }
                }
                count.countDown();
            }).start();
        }
        count.await();
        return builder.toString();
    }

    /**
     * 通过 单速率 获取信息。
     *
     * @return information
     */
    //http://localhost:44444/rate-limit/uni-rate
    @GetMapping("/uni-rate")
    public String unirate() {
        long currentTimestamp = System.currentTimeMillis();
        long lastTime = lastTimestamp.get();
        if (lastTime != 0) {
            LOG.info("当前时间戳:" + currentTimestamp + ", 与上一个时间戳的差异:" + (currentTimestamp - lastTime));
        } else {
            LOG.info("当前时间戳:" + currentTimestamp);
        }
        lastTimestamp.set(currentTimestamp);
        return "hello world 与上次请求不同的速率限制服务:" + (currentTimestamp - lastTime) + "ms.";
    }
}
